package com.iot.ic.tcp.coder;


import com.iot.ic.model.Location;
import com.iot.ic.tcp.model.MsgRequest;
import com.iot.ic.tcp.model.MsgResponse;
import com.iot.ic.tcp.netty.CustomHandler;
import com.iot.ic.tcp.netty.SendCustomHandler;
import com.iot.ic.tcp.utils.ByteUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import net.sf.json.JSONArray;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class CustomDecoder extends MessageToMessageDecoder<ByteBuf> {

	private Logger logger = LoggerFactory.getLogger(CustomDecoder.class);

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
		final byte []array;
		final int length=msg.readableBytes();
		array=new byte[length];
		msg.getBytes(msg.readerIndex(), array, 0, length);
		logger.info("上传数据"+Arrays.toString(ByteUtil.getHexString(array)));
		out.add(parseMsg(array));
		
        MsgResponse sresponse= new MsgResponse();
        ChannelHandlerContext ctxs = SendCustomHandler.channelMap.get("test");
        sresponse.setDataBytes(array);
        if (ctxs != null) {
    	  ctxs.writeAndFlush(sresponse);
         }
      
	}
	
	/**
	 * 解析公共部分，并保存为一个MsgRequest对象中
	 * @param recv
	 * @return
	 */
	private MsgRequest parseMsg(byte[] recv){
		MsgRequest msgRequest=new MsgRequest();
		msgRequest.setMessage(recv);
		String jsonStr=ByteUtil.getJsonStringByBytes(recv);
		logger.info("解析数据"+jsonStr);
		List<List<Object>> list=parseJson(jsonStr);
		if (list != null && list.size() != 0) {
			msgRequest.setChecked(checkData(list));
			List<Location> locations=parseLocations(list);
			if (locations != null && locations.size() > 0) {
				String deviceNo = locations.get(0).getDeviceName();
				msgRequest.setDeviceNo(deviceNo);
			}
			msgRequest.setLocations(locations);
			msgRequest.setDataList(list);
		} else {
			msgRequest.setChecked(false);
		}
		return msgRequest;
	}

	/**
	 * 解析json字符串
	 * @param jsonStr
	 * @return
     */
	private List<List<Object>> parseJson(String jsonStr){
		List<List<Object>> list = new ArrayList<List<Object>>();
		try {
			JSONArray jsonArray = JSONArray.fromObject(jsonStr);
			list = JSONArray.toList(jsonArray,List.class);//这里的t是Class<T>
		} catch (Exception e) {
			return list;
		}
		return list;
	}

	/**
	 * 校验上传数据是否是否符合格式
	 * @param list
	 * @return
     */
	private boolean checkData(List<List<Object>> list){
		for (List<Object> item:list
		){
			if (item.size()!=8)
				return false;
		}
		return true;
	}

	/**
	 * 解析位置信息到实体类
	 * @param list
	 * @return
     */
	private List<Location> parseLocations(List<List<Object>> list){
		List<Location>locations=new ArrayList<>();
		for (List<Object> datas:list){
			Location location=new Location();
			location.setDeviceName(String.valueOf(datas.remove(0)));
			location.setFlownum((long)(int)datas.remove(0));
			double dateStr= (double) datas.remove(0);
			long time=parseDate(dateStr);
			location.setCreateTime(time);
			location.setLocationTime(new Date(time));
			location.setLng((double)datas.remove(0));
			location.setLat((double)datas.remove(0));
			location.setAngle((double)datas.remove(0));
			locations.add(location);
		}
		return locations;
	}

	/**
	 * 解析获取上传时间戳
	 * @param dateNum
	 * @return
     */
	private long parseDate(double dateNum){
		int intNum=(int)(dateNum*1000);
		String dateStr=String.valueOf(intNum);
		int hour= 0;
		int minite= 0;
		int second= 0;
		int millisec= 0;
		if (dateStr.length() == 9) {
			String hourStr=dateStr.substring(0,2);
			hour=Integer.valueOf(hourStr);
			minite=Integer.valueOf(dateStr.substring(2,4));
			second=Integer.valueOf(dateStr.substring(4,6));
			millisec=Integer.valueOf(dateStr.substring(6));
		} else {
			String hourStr=dateStr.substring(0,1);
			hour=Integer.valueOf(hourStr);
			minite=Integer.valueOf(dateStr.substring(1,3));
			second=Integer.valueOf(dateStr.substring(3,5));
			millisec=Integer.valueOf(dateStr.substring(5));
		}
		
		Calendar ca = Calendar.getInstance();
		ca.set(ca.get(Calendar.YEAR),ca.get(Calendar.MONTH),ca.get(Calendar.DAY_OF_MONTH),hour,minite,second);
		long today= ca.getTimeInMillis()/1000*1000;
		long time=today+millisec;
		return time;
	}

}
